package com.example.rwq_test.designParttern.multiThread.readWriteLock;

/**
 * 读写锁
 *
 * @author renweiqiang
 * @version 1.0.0
 * @createTime 2022/11/9
 */
public class ReadWriteLock {
    /**
     * 正在读取的线程个数
     */
    private int readingReaders = 0;
    /**
     * 等待写的线程个数
     */
    private int waitingWriters = 0;
    /**
     * 正在写的线程个数
     */
    private int writingWriters = 0;
    /**
     * 若写入优先则为true
     */
    private boolean preferWriter = true;

    public synchronized void readLock() throws InterruptedException {
        while (writingWriters > 0 || (preferWriter && waitingWriters > 0)) {
            wait();
        }
        readingReaders++;
    }

    public synchronized void readUnlock() {
        readingReaders--;
        preferWriter = true;
        notifyAll();
    }

    public synchronized void writeLock() {
        waitingWriters++;
        try {
            while (readingReaders > 0 || writingWriters > 0) {
                wait();
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            waitingWriters--;
        }
        writingWriters++;
    }

    public synchronized void writeUnlock() {
        writingWriters--;
        preferWriter = false;
        notifyAll();
    }
}
